package il.ac.tau.cvws.scrabblesidekick.client.engine;

import il.ac.tau.cvws.scrabblesidekick.client.app.AppServices;
import il.ac.tau.cvws.scrabblesidekick.client.app.controller.CalibrationController;
import il.ac.tau.cvws.scrabblesidekick.client.ui.constant.UserMessageConstant;
import il.ac.tau.cvws.scrabblesidekick.client.util.communication.CommCallback;
import il.ac.tau.cvws.scrabblesidekick.shared.comm.request.CalibrateRequestData;
import il.ac.tau.cvws.scrabblesidekick.shared.comm.response.CalibrateResponseData;
import il.ac.tau.cvws.scrabblesidekick.shared.comm.response.ExceptionResponsePayload;
import il.ac.tau.cvws.scrabblesidekick.shared.comm.response.ResponsePayload;
import il.ac.tau.cvws.scrabblesidekick.shared.constant.CommConstants;
import il.ac.tau.cvws.scrabblesidekick.shared.datatype.ImageData;

/* The application's calibration engine. This engine is lean and is mainly
 * responsible for talking with the server and routing the response according
 * to the result.
 */
public class CalibrationEngine extends CameraEngine
{
	public CalibrationEngine(CalibrationController controller)
	{
		super(controller); 
	}
	
	/* Sends a calibration request to the server and routes the returned answer to the
	 * appropriate method in the controller, to be raised back to the platform's activity,
	 * or for any other handling the controller sees fit.
	 */
	public void handleCalibration(int screenWidth, int screenHeight, ImageData calibrationImg)
	{
		/* The calibration request consists of the high-quality board image taken by the
		 * activity and managed by the controller, and the device's screen dimensions.
		 */
		CalibrateRequestData data = new CalibrateRequestData();
		
		data.setScreenWidth(screenWidth);
		data.setScreenHeight(screenHeight);
		data.setCalibrateImage(calibrationImg);
		
		try
		{
			AppServices.instance().comm().sendPostRequest(
					CommConstants.SERVER_URL + CommConstants.CALIBRATION_SERVLET,
					CommConstants.PAYLOAD, 
					data, 
					new CommCallback()
					{
						@Override
						public void onSuccess(ResponsePayload response)
						{
							if (response instanceof ExceptionResponsePayload)
							{
								/* An exception was thrown in the server, or the calibration
								 * failed because of an applicative reason.
								 */
								_controller.handleFailure(((ExceptionResponsePayload)response).getMSG());
							}
							else
							{
								/* Calibration was successful!
								 */
								((CalibrationController)_controller).handleCalibrationSuccess(((CalibrateResponseData)response).getDataKey());
							}
						}
	
						@Override
						public void onFailure()
						{
							/* Communication error, not an applicative one.
							 */
							_controller.handleFailure(UserMessageConstant.RESPONSE_FAILED);	
						}
					});
		}
		catch (Exception e)
		{
			e.printStackTrace();
			
			/* For any unexpected runtime exception, we handle these as general failures.
			 */
			_controller.handleFailure(UserMessageConstant.RESPONSE_FAILED);
		}
	}
}
